package cms

import (
	kinit "longblog/work/base/initialize"
	kmiddleware "longblog/work/base/middleware"
	kroute "longblog/work/base/route"
	kcode "longblog/work/code"
	kbase "longblog/work/control/base"
	kdaocms "longblog/work/dao/cms"
	kutils "longblog/work/utils"
	"fmt"
	"math"
	"net/http"
	"os"
	"path"
	"regexp"
	"strconv"
	"strings"
	"time"

	kcommon "longblog/framework/tools/common"
	kgorm "longblog/framework/tools/db/gorm"

	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
	kcaptcha "github.com/mojocn/base64Captcha"
)

type Cms struct {
}

func NewCms() *Cms {
	return &Cms{}
}
func (ts *Cms) Load() []kroute.RouteWrapStruct {
	m := make([]kroute.RouteWrapStruct, 0)
	//登录相关
	m = append(m, kbase.Wrap("GET", "/login", ts.loginpage, kbase.MIDDLE_TYPE_NO_CHECK_LOGIN))
	m = append(m, kbase.Wrap("GET", "/captcha", ts.captcha, kbase.MIDDLE_TYPE_NO_CHECK_LOGIN))
	m = append(m, kbase.Wrap("POST", "/login", ts.login, kbase.MIDDLE_TYPE_NO_CHECK_LOGIN))
	//无权限提示页面
	m = append(m, kbase.Wrap("GET", "/nopermission", ts.nopermissionpage, kbase.MIDDLE_TYPE_CHECK_LOGIN))

	//主页
	m = append(m, kbase.Wrap("GET", "/logout", ts.logout, kbase.MIDDLE_TYPE_CHECK_LOGIN))
	m = append(m, kbase.Wrap("GET", "/home", ts.home, kbase.MIDDLE_TYPE_CHECK_LOGIN))
	m = append(m, kbase.Wrap("GET", "/", ts.index, kbase.MIDDLE_TYPE_CHECK_LOGIN))

	//更改个人信息
	m = append(m, kbase.Wrap("GET", "/changpwd", ts.changpwdpage, kbase.MIDDLE_TYPE_CHECK_LOGIN))
	m = append(m, kbase.Wrap("POST", "/pwdedit", ts.pwdedit, kbase.MIDDLE_TYPE_CHECK_LOGIN))
	m = append(m, kbase.Wrap("GET", "/changpic", ts.changpicpage, kbase.MIDDLE_TYPE_CHECK_LOGIN))
	m = append(m, kbase.Wrap("POST", "/checkpic", ts.checkpic, kbase.MIDDLE_TYPE_CHECK_LOGIN))
	m = append(m, kbase.Wrap("POST", "/picburstupload", ts.picburstupload, kbase.MIDDLE_TYPE_CHECK_LOGIN))
	m = append(m, kbase.Wrap("POST", "/picburstmerge", ts.picburstmerge, kbase.MIDDLE_TYPE_CHECK_LOGIN))
	//m = append(m, kbase.Wrap("POST", "/picedit", ts.picedit, kbase.MIDDLE_TYPE_CHECK_LOGIN))

	//角色管理
	m = append(m, kbase.Wrap("GET", "/role", ts.rolepage, kbase.MIDDLE_TYPE_CHECK_PERMISSION))
	m = append(m, kbase.Wrap("GET", "/roleaddpage", ts.roleaddpage, kbase.MIDDLE_TYPE_CHECK_PERMISSION))
	m = append(m, kbase.Wrap("POST", "/roleadd", ts.roleadd, kbase.MIDDLE_TYPE_CHECK_PERMISSION))
	m = append(m, kbase.Wrap("GET", "/roleeditpage", ts.roleeditpage, kbase.MIDDLE_TYPE_CHECK_PERMISSION))
	m = append(m, kbase.Wrap("POST", "/roleedit", ts.roleedit, kbase.MIDDLE_TYPE_CHECK_PERMISSION))
	m = append(m, kbase.Wrap("POST", "/roledel", ts.roledel, kbase.MIDDLE_TYPE_CHECK_PERMISSION))

	//用户管理
	m = append(m, kbase.Wrap("GET", "/user", ts.userpage, kbase.MIDDLE_TYPE_CHECK_PERMISSION))
	m = append(m, kbase.Wrap("GET", "/useraddpage", ts.useraddpage, kbase.MIDDLE_TYPE_CHECK_PERMISSION))
	m = append(m, kbase.Wrap("POST", "/useradd", ts.useradd, kbase.MIDDLE_TYPE_CHECK_PERMISSION))
	m = append(m, kbase.Wrap("GET", "/usereditpage", ts.usereditpage, kbase.MIDDLE_TYPE_CHECK_PERMISSION))
	m = append(m, kbase.Wrap("POST", "/useredit", ts.useredit, kbase.MIDDLE_TYPE_CHECK_PERMISSION))
	m = append(m, kbase.Wrap("POST", "/userdel", ts.userdel, kbase.MIDDLE_TYPE_CHECK_PERMISSION))

	//菜单管理
	m = append(m, kbase.Wrap("GET", "/permission", ts.permissionpage, kbase.MIDDLE_TYPE_CHECK_PERMISSION))
	m = append(m, kbase.Wrap("GET", "/permissionaddpage", ts.permissionaddpage, kbase.MIDDLE_TYPE_CHECK_PERMISSION))
	m = append(m, kbase.Wrap("POST", "/permissionadd", ts.permissionadd, kbase.MIDDLE_TYPE_CHECK_PERMISSION))
	m = append(m, kbase.Wrap("GET", "/permissioneditpage", ts.permissioneditpage, kbase.MIDDLE_TYPE_CHECK_PERMISSION))
	m = append(m, kbase.Wrap("POST", "/permissionedit", ts.permissionedit, kbase.MIDDLE_TYPE_CHECK_PERMISSION))
	m = append(m, kbase.Wrap("POST", "/permissiondel", ts.permissiondel, kbase.MIDDLE_TYPE_CHECK_PERMISSION))

	//权限分配相关
	m = append(m, kbase.Wrap("POST", "/getpermissionsofrole", ts.getpermissionsofrole, kbase.MIDDLE_TYPE_CHECK_PERMISSION))
	m = append(m, kbase.Wrap("GET", "/permissionsofrole", ts.permissionsofrolepage, kbase.MIDDLE_TYPE_CHECK_PERMISSION))
	m = append(m, kbase.Wrap("POST", "/permissionsofrolesave", ts.permissionsofrolesave, kbase.MIDDLE_TYPE_CHECK_PERMISSION))

	//日志管理
	m = append(m, kbase.Wrap("GET", "/logrecord", ts.logrecordpage, kbase.MIDDLE_TYPE_CHECK_PERMISSION))
	m = append(m, kbase.Wrap("POST", "/logrecorddel", ts.logrecorddel, kbase.MIDDLE_TYPE_CHECK_PERMISSION))

	return m
}

//-----------------------------------------------------------------------------------

func (ts *Cms) loginpage(c *gin.Context) {
	session := sessions.Default(c)
	v := session.Get("user")
	if v != nil {
		c.Redirect(http.StatusMovedPermanently, "/")
		return
	}
	c.HTML(http.StatusOK, "cms/login.html", gin.H{})

}

//-----------------------------------------------------------------------------------

func (ts *Cms) captcha(c *gin.Context) {
	session := sessions.Default(c)
	/*configD := kcaptcha.ConfigDigit{
		Height:     80,
		Width:      200,
		MaxSkew:    0.7,
		DotCount:   80,
		CaptchaLen: 4,
	}*/
	configC := kcaptcha.ConfigCharacter{
		Height: 40,
		Width:  160,
		//const CaptchaModeNumber:数字,CaptchaModeAlphabet:字母,CaptchaModeArithmetic:算术,CaptchaModeNumberAlphabet:数字字母混合.
		Mode:               kcaptcha.CaptchaModeNumberAlphabet,
		ComplexOfNoiseText: kcaptcha.CaptchaComplexLower,
		ComplexOfNoiseDot:  kcaptcha.CaptchaComplexLower,
		IsShowHollowLine:   false,
		IsShowNoiseDot:     false,
		IsShowNoiseText:    false,
		IsShowSlimeLine:    false,
		IsShowSineLine:     false,
		CaptchaLen:         4,
	}
	idKeyC, capC := kcaptcha.GenerateCaptcha("", configC)
	base64Png := kcaptcha.CaptchaWriteToBase64Encoding(capC)
	session.Set("captchaId", idKeyC)
	_ = session.Save()
	c.String(http.StatusOK, base64Png)
}

//-----------------------------------------------------------------------------------
// http://127.0.0.1:8082/login?name=admin&passwd=123456

type loginBind struct {
	Name    string `form:"name"  binding:"required"`
	Passwd  string `form:"passwd"  binding:"required"`
	Captcha string `form:"captcha"  binding:"required"`
}

func (ts *Cms) login(c *gin.Context) {
	var param loginBind
	if err := c.ShouldBind(&param); err != nil {
		kinit.LogError.Println(err)
		c.Redirect(http.StatusMovedPermanently, "/login")
	}

	session := sessions.Default(c)
	idKey := session.Get("captchaId")
	key := fmt.Sprintf("%s", idKey)
	verify := kcaptcha.VerifyCaptcha(key, param.Captcha)
	if !verify {
		c.Redirect(http.StatusMovedPermanently, "/login")
		return
	}
	session.Delete("captchaId")
	_ = session.Save()
	obj := kdaocms.GetCmsAdminUsersByName(nil, param.Name)
	if obj.ID > 0 {
		if ok := kutils.PasswordVerify(param.Passwd, obj.Password); ok {
			//进行session设置
			session := sessions.Default(c)
			session.Set("user", obj.ID)
			session.Set("user_name", obj.Name)
			session.Set("user_avatar", obj.Avatar)
			if err := session.Save(); err != nil {
				c.Redirect(http.StatusMovedPermanently, "/login")
				return
			}
			_ = kdaocms.UpdateCmsAdminUsersLoginInfoById(nil, obj.ID, c.ClientIP())
			c.Redirect(http.StatusMovedPermanently, "/")
			return
		}
	}
	c.Redirect(http.StatusMovedPermanently, "/login")
	return
}

func (ts *Cms) logout(c *gin.Context) {
	callbackName := kbase.GetParam(c, "callback")
	session := sessions.Default(c)
	v := session.Get("user")
	if v == nil {
		kinit.LogError.Println("session is nil")
		kbase.SendErrorJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}
	session.Delete("user")
	session.Delete("user_name")
	session.Delete("user_avatar")
	session.Delete("token")
	if err := session.Save(); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}
	kbase.SendErrorJsonStr(c, kcode.SUCCESS_STATUS, "")
}

//-----------------------------------------------------------------------------------

func (ts *Cms) index(c *gin.Context) {
	session := sessions.Default(c)
	pic := session.Get("user_avatar")
	value, _ := c.Get("user")
	userId := kutils.AssertInt64(value)
	name := c.GetString("user_name")
	roleId := kdaocms.GetCmsAdminUserHasRoleByRaw(nil, userId)
	objs := kdaocms.GetCmsAdminRoleIdHasPermissionsByRaw(nil, roleId.RoleId)
	m := &kutils.Menu{}
	c.HTML(http.StatusOK, "cms/index.html", gin.H{
		"lists": m.MenuList(objs),
		"name":  name,
		"pic":   pic,
	})
}

func (ts *Cms) home(c *gin.Context) {
	c.HTML(http.StatusOK, "cms/home.html", gin.H{})
}

func (ts *Cms) nopermissionpage(c *gin.Context) {
	c.HTML(http.StatusOK, "cms/no_permission.html", gin.H{
		"msg":  "无权限访问此页面",
		"code": 401,
		"wait": 3,
	})
}

//-----------------------------------------------------------------------------------

func (ts *Cms) rolepage(c *gin.Context) {
	objs := kdaocms.GetCmsAdminRoles(nil)
	count := len(objs)
	for i := 0; i < count; i++ {
		objs[i].CreatedAt = kutils.FormatTime(objs[i].CreatedAt)
	}
	c.HTML(http.StatusOK, "cms/role_list.html", gin.H{
		"lists": objs,
		"token": c.GetString("token"),
	})
}

func (ts *Cms) roleaddpage(c *gin.Context) {
	c.HTML(http.StatusOK, "cms/role_add.html", gin.H{
		"token": c.GetString("token"),
	})
}

type roleaddBind struct {
	Name string `form:"name"  binding:"required"`
}

func (ts *Cms) roleadd(c *gin.Context) {
	var param roleaddBind
	callbackName := kbase.GetParam(c, "callback")
	if err := c.ShouldBind(&param); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.PARAM_WRONG, callbackName)
		return
	}

	param.Name = strings.Replace(param.Name, " ", "", -1)
	re := regexp.MustCompile("^[A-Za-z\\x{4e00}-\\x{9fa5}]*$")
	ok := re.Match([]byte(param.Name))
	if !ok {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_NAME_ILLEGAL_CHAR_CHINESE, callbackName)
		return
	}

	obj := kdaocms.GetCmsAdminRolesByName(nil, param.Name)
	if obj.ID > 0 {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_NAME_EXIST, callbackName)
		return
	}

	if _, err := kdaocms.InsertCmsAdminRoles(nil, param.Name); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}
	kbase.SendErrorJsonStr(c, kcode.SUCCESS_STATUS, "")
}

func (ts *Cms) roleeditpage(c *gin.Context) {
	idStr := kbase.GetParam(c, "id")
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		c.Redirect(http.StatusMovedPermanently, "/role")
	}
	objs := kdaocms.GetCmsAdminRolesById(nil, id)
	c.HTML(http.StatusOK, "cms/role_edit.html", gin.H{
		"token": c.GetString("token"),
		"obj":   objs,
	})
}

type roleeditBind struct {
	ID   int64  `form:"id"  binding:"required"`
	Name string `form:"name"  binding:"required"`
}

func (ts *Cms) roleedit(c *gin.Context) {
	var param roleeditBind
	callbackName := kbase.GetParam(c, "callback")
	if err := c.ShouldBind(&param); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.PARAM_WRONG, callbackName)
		return
	}

	param.Name = strings.Replace(param.Name, " ", "", -1)
	re := regexp.MustCompile("^[A-Za-z\\x{4e00}-\\x{9fa5}]*$")
	ok := re.Match([]byte(param.Name))
	if !ok {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_NAME_ILLEGAL_CHAR_CHINESE, callbackName)
		return
	}

	if param.ID == 1 {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_SUPER_ROLE_OPERATION, callbackName)
		return
	}

	obj := kdaocms.GetCmsAdminRolesByName(nil, param.Name)
	if obj.ID > 0 && obj.ID != param.ID {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_NAME_EXIST, callbackName)
		return
	}

	if err := kdaocms.UpdateCmsAdminRolesById(nil, param.ID, param.Name); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}
	kbase.SendErrorJsonStr(c, kcode.SUCCESS_STATUS, "")

}

type roledelBind struct {
	ID int64 `form:"id"  binding:"required"`
}

func (ts *Cms) roledel(c *gin.Context) {
	var param roledelBind
	callbackName := kbase.GetParam(c, "callback")
	if err := c.ShouldBind(&param); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.PARAM_WRONG, callbackName)
		return
	}

	if param.ID == 1 {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_SUPER_ROLE_OPERATION, callbackName)
		return
	}

	transaction := kgorm.NewTransaction()
	tx := transaction.Begin(kinit.Gorm)
	defer func() {
		_ = transaction.Defer()
	}()

	if err := kdaocms.DelCmsAdminUserHasRolesByRoleId(tx, param.ID); err != nil {
		_ = transaction.Rollback()
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}

	if err := kdaocms.DelCmsAdminRoleHasPermissionsByRoleId(tx, param.ID); err != nil {
		_ = transaction.Rollback()
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}

	if err := kdaocms.DelCmsAdminRolesById(tx, param.ID); err != nil {
		_ = transaction.Rollback()
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}

	kbase.SendErrorJsonStr(c, kcode.SUCCESS_STATUS, "")

}

//----------------------------------------------------------------------------------------

func (ts *Cms) changpwdpage(c *gin.Context) {
	c.HTML(http.StatusOK, "cms/chang_pwd.html", gin.H{
		"token": c.GetString("token"),
	})
}

type pwdBind struct {
	OldPasswd     string `form:"old_passwd"  binding:"required"`
	Passwd        string `form:"passwd"  binding:"required"`
	ConfirmPasswd string `form:"confirm_passwd"  binding:"required"`
}

func (ts *Cms) pwdedit(c *gin.Context) {
	var param pwdBind
	callbackName := kbase.GetParam(c, "callback")
	if err := c.ShouldBind(&param); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.PARAM_WRONG, callbackName)
		return
	}

	lenPwd := len(param.Passwd)
	if lenPwd < 6 || lenPwd > 20 {
		kbase.SendErrorTokenJsonStr(c, kcode.PASSWD_TOO_SHORT, callbackName)
		return
	}

	if param.Passwd != param.ConfirmPasswd {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_PASSWD_CONFIRM, callbackName)
		return
	}

	value, _ := c.Get("user")
	userId := kutils.AssertInt64(value)
	user := kdaocms.GetCmsAdminUsersById(nil, userId)
	if ok := kutils.PasswordVerify(param.OldPasswd, user.Password); !ok {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_PASSWORD, callbackName)
		return
	}

	password, err := kutils.PasswordHash(param.Passwd)
	if err != nil {
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}

	if param.Passwd == param.OldPasswd {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_PASSWD_SAMPLE, callbackName)
		return
	}

	if err := kdaocms.UpdateCmsAdminUsersById(nil, userId, password); err != nil {
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}
	kbase.SendErrorJsonStr(c, kcode.SUCCESS_STATUS, "")
}

func (ts *Cms) changpicpage(c *gin.Context) {
	value, _ := c.Get("user")
	userId := kutils.AssertInt64(value)
	session := sessions.Default(c)
	pic := session.Get("user_avatar")
	c.HTML(http.StatusOK, "cms/chang_pic.html", gin.H{
		"token":  c.GetString("token"),
		"pic":    pic,
		"userId": userId,
	})
}

type checkPicBind struct {
	Filename string `form:"filename"  binding:"required"`
	Dir      string `form:"dir"  binding:"required"`
	Total    int64  `form:"total"  binding:"required"`
	Size     string `form:"size"  binding:"required"`
}

func (ts *Cms) checkpic(c *gin.Context) {
	var param checkPicBind
	callbackName := kbase.GetParam(c, "callback")
	if err := c.ShouldBind(&param); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.PARAM_WRONG, callbackName)
		return
	}

	fileExt := strings.ToLower(path.Ext(param.Filename))
	isExt := strings.Replace(fileExt, ".", "", -1)
	if !(isExt == "jpg" || isExt == "jpeg" || isExt == "png" || isExt == "bmp") {
		kbase.SendErrorTokenJsonStr(c, kcode.FAIL_SUFFIX_FILE, callbackName)
		return
	}

	root, err := kutils.GetCurrentPath()
	if err != nil {
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}

	value, _ := c.Get("user")
	userId := kutils.AssertInt64(value)
	obj := kdaocms.GetCmsBurstRecordByUidAndFilename(nil, userId, param.Filename)
	if obj.ID > 0 {
		if param.Size == obj.FileTotalSize {
			kbase.SendErrorOriginJsonStr(c, kcode.SUCCESS_STATUS, gin.H{
				"count": obj.BurstCount,
				"id":    obj.ID,
				"dir":   obj.TempFolderName,
				"token": kmiddleware.GetPreventToken(c),
			}, callbackName)
			return
		} else {
			dir := fmt.Sprintf("%s%s%s", root, kcode.BURST_UPLOAD_TMP_DIR, obj.TempFolderName)
			if err := os.RemoveAll(dir); err != nil {
				kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
				return
			}
			if err := kdaocms.DelCmsBurstRecordById(nil, obj.ID); err != nil {
				kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
				return
			}
		}
	}
	record, err := kdaocms.InsertCmsBurstRecord(nil, userId, param.Dir, param.Filename, param.Size, param.Total)
	if err != nil {
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}
	kbase.SendErrorOriginJsonStr(c, kcode.SUCCESS_STATUS, gin.H{
		"count": record.BurstCount,
		"id":    record.ID,
		"token": kmiddleware.GetPreventToken(c),
	}, callbackName)

}

type picburstuploadBind struct {
	Filename string `form:"filename"  binding:"required"`
	Dir      string `form:"dir"  binding:"required"`
	Index    int64  `form:"index"  binding:"required"`
	RecordId int64  `form:"record_id"  binding:"required"`
}

func (ts *Cms) picburstupload(c *gin.Context) {
	var param picburstuploadBind
	callbackName := kbase.GetParam(c, "callback")
	if err := c.ShouldBind(&param); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.PARAM_WRONG, callbackName)
		return
	}

	fileExt := strings.ToLower(path.Ext(param.Filename))
	isExt := strings.Replace(fileExt, ".", "", -1)
	if !(isExt == "jpg" || isExt == "jpeg" || isExt == "png" || isExt == "bmp") {
		kbase.SendErrorTokenJsonStr(c, kcode.FAIL_SUFFIX_FILE, callbackName)
		return
	}

	_, fileHeader, err := c.Request.FormFile("file")
	if err == nil {
		root, err := kutils.GetCurrentPath()
		if err != nil {
			kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
			return
		}
		dir := fmt.Sprintf("%s%s%s", root, kcode.BURST_UPLOAD_TMP_DIR, param.Dir)
		err, code, _, _ := kutils.SaveBurstFile(c, dir, param.Index, fileExt, fileHeader)
		if err != nil {
			kinit.LogError.Println(err)
			kbase.SendErrorTokenJsonStr(c, code, callbackName)
			return
		}

		if err := kdaocms.UpdateCmsBurstRecordById(nil, param.RecordId, param.Index); err != nil {
			kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
			return
		}
		kbase.SendErrorTokenJsonStr(c, kcode.FILE_UPLOAD_KEEP, callbackName)
	} else {
		kbase.SendErrorTokenJsonStr(c, kcode.FILE_UPLOAD_FAIL, callbackName)
	}
}

type picburstmergeBind struct {
	Filename string `form:"filename"  binding:"required"`
	Dir      string `form:"dir"  binding:"required"`
	AllCount int64  `form:"all_count"  binding:"required"`
	RecordId int64  `form:"record_id"  binding:"required"`
}

func (ts *Cms) picburstmerge(c *gin.Context) {
	var param picburstmergeBind
	callbackName := kbase.GetParam(c, "callback")
	if err := c.ShouldBind(&param); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.PARAM_WRONG, callbackName)
		return
	}

	root, err := kutils.GetCurrentPath()
	if err != nil {
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}
	dir := fmt.Sprintf("%s%s%s", root, kcode.BURST_UPLOAD_TMP_DIR, param.Dir)
	fileExt := path.Ext(param.Filename)

	fileNum, _, err := kutils.GetOneDirFileNum(dir)
	if err != nil {
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}

	if fileNum != param.AllCount {
		if err := os.RemoveAll(dir); err != nil {
			kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
			return
		}
		if err := kdaocms.DelCmsBurstRecordById(nil, param.RecordId); err != nil {
			kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
			return
		}
		kbase.SendErrorTokenJsonStr(c, kcode.FILE_UPLOAD_FAIL, callbackName)
		return
	}

	randNum := kcommon.GetRandomString(6, 0)
	times := strconv.FormatInt(time.Now().UnixNano(), 10)
	savePath := fmt.Sprintf("%s%s%s", times, randNum, fileExt)
	outPutFile := fmt.Sprintf("%s%s%s", root, kcode.AVATER_SAVE_PATH, savePath)
	if err := kutils.MergeFile(outPutFile, dir, int(fileNum), fileExt); err != nil {
		kinit.LogError.Println(err)
		_ = os.Remove(outPutFile)
		kbase.SendErrorTokenJsonStr(c, kcode.FAIL_MERGE_FILE, callbackName)
		return
	}

	if err := os.RemoveAll(dir); err != nil {
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}

	transaction := kgorm.NewTransaction()
	tx := transaction.Begin(kinit.Gorm)
	defer func() {
		_ = transaction.Defer()
	}()

	if err := kdaocms.DelCmsBurstRecordById(tx, param.RecordId); err != nil {
		_ = transaction.Rollback()
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}

	value, _ := c.Get("user")
	userId := kutils.AssertInt64(value)
	objs := kdaocms.GetCmsAdminUsersById(tx, userId)
	pic := objs.Avatar

	url := fmt.Sprintf("%s%s", kcode.DEFAULT_AVATER_STATIC_DIR, savePath)
	if err := kdaocms.UpdateCmsAdminUsersPicById(tx, userId, url); err != nil {
		_ = transaction.Rollback()
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}
	session := sessions.Default(c)
	session.Set("user_avatar", url)
	_ = session.Save()

	if pic != "" && pic != kcode.DEFAULT_AVATER {
		_ = os.Remove(fmt.Sprintf("%s%s%s", root, kcode.AVATER_SAVE_PARENT_PATH, pic))
	}

	kbase.SendErrorJsonStr(c, kcode.SUCCESS_STATUS, "")
}

/*func (ts *Cms) picedit(c *gin.Context) {
	value, _ := c.Get("user")
	userId := kutils.AssertInt64(value)
	callbackName := kbase.GetParam(c, "callback")
	_, fileHeader, err := c.Request.FormFile("file")
	if err == nil {
		root, err := kutils.GetCurrentPath()
		if err != nil {
			kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
			return
		}
		dir := fmt.Sprintf("%s%s", root, kcode.AVATER_SAVE_PATH)
		err, code, savePath, _ := kutils.SaveFile(c, dir, fileHeader)
		if err != nil {
			kinit.LogError.Println(err)
			kbase.SendErrorTokenJsonStr(c, code, callbackName)
			return
		}

		objs := kdaocms.GetCmsAdminUsersById(nil, userId)
		pic := objs.Avatar

		path := fmt.Sprintf("%s%s", kcode.DEFAULT_AVATER_STATIC_DIR, savePath)
		if err := kdaocms.UpdateCmsAdminUsersPicById(nil, userId, path); err != nil {
			kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
			return
		}

		session := sessions.Default(c)
		session.Set("user_avatar", path)
		_ = session.Save()

		if pic != "" && pic != kcode.DEFAULT_AVATER {
			_ = os.Remove(fmt.Sprintf("%s%s%s", root, kcode.AVATER_SAVE_PARENT_PATH, pic))
		}

	} else {
		kbase.SendErrorTokenJsonStr(c, kcode.FILE_UPLOAD_FAIL, callbackName)
		return
	}

	kbase.SendErrorJsonStr(c, kcode.SUCCESS_STATUS, "")
}*/

//-----------------------------------------------------------------------------------

func (ts *Cms) userpage(c *gin.Context) {
	searchName := kbase.GetParam(c, "search_name")
	objs := kdaocms.GetCmsAdminUsers(nil, searchName)
	count := len(objs)
	for i := 0; i < count; i++ {
		objs[i].CreatedAt = kutils.FormatTime(objs[i].CreatedAt)
		objs[i].LoginAt = kutils.FormatTime(objs[i].LoginAt)
	}
	c.HTML(http.StatusOK, "cms/user_list.html", gin.H{
		"searchName": searchName,
		"lists":      objs,
		"token":      c.GetString("token"),
	})
}

func (ts *Cms) useraddpage(c *gin.Context) {
	objs := kdaocms.GetCmsAdminRoles(nil)
	c.HTML(http.StatusOK, "cms/user_add.html", gin.H{
		"token": c.GetString("token"),
		"lists": objs,
	})
}

type useraddBind struct {
	Name   string `form:"name"  binding:"required"`
	Passwd string `form:"passwd"  binding:"required"`
	RoleId int64  `form:"role_id"  binding:"exists"`
}

func (ts *Cms) useradd(c *gin.Context) {
	var param useraddBind
	callbackName := kbase.GetParam(c, "callback")
	if err := c.ShouldBind(&param); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.PARAM_WRONG, callbackName)
		return
	}

	if param.RoleId == 0 {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_PERMISSION_NO_SELECT, callbackName)
		return
	}

	lenPwd := len(param.Passwd)
	if lenPwd < 6 || lenPwd > 20 {
		kbase.SendErrorTokenJsonStr(c, kcode.PASSWD_TOO_SHORT, callbackName)
		return
	}

	obj := kdaocms.GetCmsAdminUsersByName(nil, param.Name)
	if obj.ID > 0 {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_NAME_EXIST, callbackName)
		return
	}

	param.Name = strings.Replace(param.Name, " ", "", -1)
	re := regexp.MustCompile("^[a-zA-Z][A-Za-z0-9]*$")
	ok := re.Match([]byte(param.Name))
	if !ok {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_NAME_ILLEGAL_CHAR, callbackName)
		return
	}

	password, err := kutils.PasswordHash(param.Passwd)
	if err != nil {
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}

	transaction := kgorm.NewTransaction()
	tx := transaction.Begin(kinit.Gorm)
	defer func() {
		_ = transaction.Defer()
	}()

	objs, err := kdaocms.InsertCmsAdminUsers(tx, param.Name, password, kcode.DEFAULT_AVATER, c.ClientIP())
	if err != nil {
		_ = transaction.Rollback()
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}

	if _, err := kdaocms.InsertCmsAdminUserHasRoles(tx, objs.ID, param.RoleId); err != nil {
		_ = transaction.Rollback()
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}

	kbase.SendErrorJsonStr(c, kcode.SUCCESS_STATUS, "")
}

func (ts *Cms) usereditpage(c *gin.Context) {
	idStr := kbase.GetParam(c, "id")
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		c.Redirect(http.StatusMovedPermanently, "/user")
	}
	objs := kdaocms.GetCmsAdminUsersById(nil, id)
	obj := kdaocms.GetCmsAdminRoles(nil)
	userRole := kdaocms.GetCmsAdminUserHasRolesByAdminId(nil, id)
	c.HTML(http.StatusOK, "cms/user_edit.html", gin.H{
		"token":  c.GetString("token"),
		"obj":    objs,
		"roleId": userRole.RoleId,
		"lists":  obj,
	})
}

type usereditBind struct {
	ID     int64  `form:"id"  binding:"required"`
	Name   string `form:"name"  binding:"required"`
	Passwd string `form:"passwd"  binding:"exists"`
	RoleId int64  `form:"role_id"  binding:"exists"`
}

func (ts *Cms) useredit(c *gin.Context) {
	var param usereditBind
	callbackName := kbase.GetParam(c, "callback")
	if err := c.ShouldBind(&param); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.PARAM_WRONG, callbackName)
		return
	}

	if param.RoleId == 0 {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_PERMISSION_NO_SELECT, callbackName)
		return
	}

	if param.ID == 1 {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_SUPER_ROLE_OPERATION, callbackName)
		return
	}

	obj := kdaocms.GetCmsAdminUsersByName(nil, param.Name)
	if obj.ID > 0 && obj.ID != param.ID {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_NAME_EXIST, callbackName)
		return
	}

	param.Name = strings.Replace(param.Name, " ", "", -1)
	re := regexp.MustCompile("^[a-zA-Z][A-Za-z0-9]*$")
	ok := re.Match([]byte(param.Name))
	if !ok {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_NAME_ILLEGAL_CHAR, callbackName)
		return
	}

	password := ""
	if param.Passwd != "" {
		lenPwd := len(param.Passwd)
		if lenPwd < 6 || lenPwd > 20 {
			kbase.SendErrorTokenJsonStr(c, kcode.PASSWD_TOO_SHORT, callbackName)
			return
		}
		pwd, err := kutils.PasswordHash(param.Passwd)
		if err != nil {
			kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
			return
		}
		password = pwd
	}

	transaction := kgorm.NewTransaction()
	tx := transaction.Begin(kinit.Gorm)
	defer func() {
		_ = transaction.Defer()
	}()

	if err := kdaocms.UpdateCmsAdminUsersAllById(tx, param.ID, param.Name, password); err != nil {
		_ = transaction.Rollback()
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}

	objs := kdaocms.GetCmsAdminUserHasRolesByAdminId(tx, param.ID)
	if objs.ID > 0 {
		if err := kdaocms.UpdateCmsAdminUserHasRolesByAdminId(tx, param.ID, param.RoleId); err != nil {
			_ = transaction.Rollback()
			kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
			return
		}
	} else {
		if _, err := kdaocms.InsertCmsAdminUserHasRoles(tx, param.ID, param.RoleId); err != nil {
			_ = transaction.Rollback()
			kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
			return
		}
	}

	kbase.SendErrorJsonStr(c, kcode.SUCCESS_STATUS, "")

}

type userdelBind struct {
	ID int64 `form:"id"  binding:"required"`
}

func (ts *Cms) userdel(c *gin.Context) {
	var param userdelBind
	callbackName := kbase.GetParam(c, "callback")
	if err := c.ShouldBind(&param); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.PARAM_WRONG, callbackName)
		return
	}

	if param.ID == 1 {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_SUPER_ROLE_OPERATION, callbackName)
		return
	}

	transaction := kgorm.NewTransaction()
	tx := transaction.Begin(kinit.Gorm)
	defer func() {
		_ = transaction.Defer()
	}()

	objs := kdaocms.GetCmsAdminUsersById(nil, param.ID)
	pic := objs.Avatar
	if pic != "" && pic != kcode.DEFAULT_AVATER {
		root, err := kutils.GetCurrentPath()
		if err != nil {
			kbase.SendErrorTokenJsonStr(c, kcode.PARAM_WRONG, callbackName)
			return
		}
		url := fmt.Sprintf("%s%s%s", root, kcode.AVATER_SAVE_PARENT_PATH, objs.Avatar)
		_ = os.Remove(url)
	}

	if err := kdaocms.DelCmsAdminUsersById(tx, param.ID); err != nil {
		_ = transaction.Rollback()
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}

	if err := kdaocms.DelCmsAdminUserHasRolesByAdminId(tx, param.ID); err != nil {
		_ = transaction.Rollback()
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}

	kbase.SendErrorJsonStr(c, kcode.SUCCESS_STATUS, "")

}

//-----------------------------------------------------------------------------------

func (ts *Cms) permissionpage(c *gin.Context) {
	objs := kdaocms.GetCmsAdminPermissions(nil)
	m := &kutils.Menu{}
	c.HTML(http.StatusOK, "cms/permission_list.html", gin.H{
		"lists": m.MenuMerge(objs),
		"token": c.GetString("token"),
	})
}

func (ts *Cms) permissionaddpage(c *gin.Context) {
	idStr := kbase.GetParam(c, "id")
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		c.Redirect(http.StatusMovedPermanently, "/permission")
	}
	objs := kdaocms.GetCmsAdminPermissions(nil)
	m := &kutils.Menu{}
	c.HTML(http.StatusOK, "cms/permission_add.html", gin.H{
		"token":        c.GetString("token"),
		"permissionId": id,
		"lists":        m.MenuMerge(objs),
	})
}

type permissionaddBind struct {
	Name string `form:"name"  binding:"required"`
	Path string `form:"path"  binding:"exists"`
	PID  string `form:"pid"  binding:"required"`
	Show int64  `form:"show"  binding:"required"`
}

func (ts *Cms) permissionadd(c *gin.Context) {
	var param permissionaddBind
	callbackName := kbase.GetParam(c, "callback")
	if err := c.ShouldBind(&param); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.PARAM_WRONG, callbackName)
		return
	}

	pid, err := strconv.ParseInt(param.PID, 10, 64)
	if err != nil {
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}

	if pid != 0 && param.Path == "" {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_PERMISSION_PATH_EMPTY, callbackName)
		return
	}

	param.Name = strings.Replace(param.Name, " ", "", -1)
	param.Path = strings.Replace(param.Path, " ", "", -1)
	re := regexp.MustCompile("^[A-Za-z\\x{4e00}-\\x{9fa5}]*$")
	ok := re.Match([]byte(param.Name))
	if !ok {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_NAME_ILLEGAL_CHAR_CHINESE, callbackName)
		return
	}

	obj := kdaocms.GetCmsAdminPermissionsByNamePidPath(nil, param.Name, pid, param.Path)
	if obj.ID > 0 {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_NAME_EXIST, callbackName)
		return
	}

	if param.Path != "" {
		paths := kdaocms.GetCmsAdminPermissionsByPath(nil, param.Path)
		if paths.ID > 0 {
			kbase.SendErrorTokenJsonStr(c, kcode.WRONG_PATH_EXIST, callbackName)
			return
		}
	}

	if param.Show == 2 {
		param.Show = 0
	}

	if _, err := kdaocms.InsertCmsAdminPermissions(nil, param.Name, pid, param.Path, param.Show); err != nil {
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}
	kbase.SendErrorJsonStr(c, kcode.SUCCESS_STATUS, "")
}

func (ts *Cms) permissioneditpage(c *gin.Context) {
	idStr := kbase.GetParam(c, "id")
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		c.Redirect(http.StatusMovedPermanently, "/permission")
	}
	objs := kdaocms.GetCmsAdminPermissions(nil)
	obj := kdaocms.GetCmsAdminPermissionsById(nil, id)
	m := &kutils.Menu{}
	c.HTML(http.StatusOK, "cms/permission_edit.html", gin.H{
		"token": c.GetString("token"),
		"lists": m.MenuMerge(objs),
		"obj":   obj,
	})
}

type permissioneditBind struct {
	ID   int64  `form:"id"  binding:"required"`
	Name string `form:"name"  binding:"required"`
	Path string `form:"path"  binding:"exists"`
	PID  string `form:"pid"  binding:"required"`
	Show int64  `form:"show"  binding:"required"`
}

func (ts *Cms) permissionedit(c *gin.Context) {
	var param permissioneditBind
	callbackName := kbase.GetParam(c, "callback")
	if err := c.ShouldBind(&param); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.PARAM_WRONG, callbackName)
		return
	}

	pid, err := strconv.ParseInt(param.PID, 10, 64)
	if err != nil {
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}

	if pid != 0 && param.Path == "" {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_PERMISSION_PATH_EMPTY, callbackName)
		return
	}

	param.Name = strings.Replace(param.Name, " ", "", -1)
	param.Path = strings.Replace(param.Path, " ", "", -1)
	re := regexp.MustCompile("^[A-Za-z\\x{4e00}-\\x{9fa5}]*$")
	ok := re.Match([]byte(param.Name))
	if !ok {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_NAME_ILLEGAL_CHAR_CHINESE, callbackName)
		return
	}

	obj := kdaocms.GetCmsAdminPermissionsByNamePidPath(nil, param.Name, pid, param.Path)
	if obj.ID > 0 && obj.ID != param.ID {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_NAME_EXIST, callbackName)
		return
	}

	if param.Path != "" {
		paths := kdaocms.GetCmsAdminPermissionsByPath(nil, param.Path)
		if paths.ID > 0 && paths.ID != param.ID {
			kbase.SendErrorTokenJsonStr(c, kcode.WRONG_PATH_EXIST, callbackName)
			return
		}
	}

	if param.Show == 2 {
		param.Show = 0
	}

	if err := kdaocms.UpdateCmsAdminPermissionsById(nil, param.ID, param.Name, pid, param.Path, param.Show); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}
	kbase.SendErrorJsonStr(c, kcode.SUCCESS_STATUS, "")

}

type permissiondelBind struct {
	ID int64 `form:"id"  binding:"required"`
}

func (ts *Cms) permissiondel(c *gin.Context) {
	var param permissiondelBind
	callbackName := kbase.GetParam(c, "callback")
	if err := c.ShouldBind(&param); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.PARAM_WRONG, callbackName)
		return
	}

	objs := kdaocms.GetCmsAdminPermissions(nil)
	m := &kutils.Menu{}
	lists := m.DelMergeId(param.ID, objs)

	ids := []int64{param.ID}
	for _, v := range lists {
		ids = append(ids, v.ID)
	}

	transaction := kgorm.NewTransaction()
	tx := transaction.Begin(kinit.Gorm)
	defer func() {
		_ = transaction.Defer()
	}()

	if err := kdaocms.DelCmsAdminPermissionsById(tx, ids); err != nil {
		_ = transaction.Rollback()
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}

	if err := kdaocms.DelCmsAdminRoleHasPermissionsByPermissionId(tx, ids); err != nil {
		_ = transaction.Rollback()
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}

	kbase.SendErrorJsonStr(c, kcode.SUCCESS_STATUS, "")

}

//-----------------------------------------------------------------------------------

func (ts *Cms) permissionsofrolepage(c *gin.Context) {
	idStr := kbase.GetParam(c, "id")
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		c.Redirect(http.StatusMovedPermanently, "/role")
	}
	c.HTML(http.StatusOK, "cms/role_permission.html", gin.H{
		"role_id": id,
		"token":   c.GetString("token"),
	})
}

type getpermissionsofroleBind struct {
	RoleId int64 `form:"role_id"  binding:"required"`
}

func (ts *Cms) getpermissionsofrole(c *gin.Context) {
	var param getpermissionsofroleBind
	callbackName := kbase.GetParam(c, "callback")
	if err := c.ShouldBind(&param); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.PARAM_WRONG, callbackName)
		return
	}

	objs := kdaocms.GetCmsAdminPermissions(nil)
	m := &kutils.Menu{}
	lists := m.MenuMerge(objs)

	roles := kdaocms.GetCmsAdminRoleHasPermissionsByRoleId(nil, param.RoleId)

	block := make([]kutils.PermissionMenu, 0)
	for _, v := range lists {
		tmp := kutils.PermissionMenu{
			ID:      v.ID,
			Name:    v.Name,
			Pid:     v.Pid,
			Level:   v.Level,
			Open:    false,
			Checked: false,
		}
		if _, ok := roles[v.ID]; ok {
			tmp.Checked = true
		}
		if v.Pid == 0 {
			tmp.Open = true
		}
		block = append(block, tmp)
	}

	kbase.SendErrorOriginJsonStr(c, kcode.SUCCESS_STATUS, gin.H{
		"token": kmiddleware.GetPreventToken(c),
		"lists": block,
	}, callbackName)
}

type permissionsofrolesaveBind struct {
	RoleId      int64   `form:"role_id"  binding:"required"`
	Permissions []int64 `form:"permissions"  binding:"exists"`
}

func (ts *Cms) permissionsofrolesave(c *gin.Context) {
	var param permissionsofrolesaveBind
	callbackName := kbase.GetParam(c, "callback")
	if err := c.ShouldBind(&param); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.PARAM_WRONG, callbackName)
		return
	}

	count := len(param.Permissions)
	oldPermission := kdaocms.GetCmsAdminRoleHasPermissionsByRoleId(nil, param.RoleId)
	countP := len(oldPermission)
	if count == 0 {
		if param.RoleId == 1 {
			kbase.SendErrorTokenJsonStr(c, kcode.WRONG_PERMISSION_EMPTY, "")
			return
		}
		if countP > 0 {
			if err := kdaocms.DelCmsAdminRoleHasPermissionsByRoleId(nil, param.RoleId); err != nil {
				kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
				return
			}
		}
	} else {
		if countP > 0 {
			existsIds := make(map[int64]int64, 0)
			deleteIds := make([]int64, 0)
			saveIds := make([]int64, 0)
			for _, v := range param.Permissions {
				if _, ok := oldPermission[v]; !ok {
					saveIds = append(saveIds, v)
				} else {
					existsIds[v] = v
				}
			}
			for k := range oldPermission {
				if _, ok := existsIds[k]; !ok {
					deleteIds = append(deleteIds, k)
				}
			}
			if len(deleteIds) > 0 {
				if err := kdaocms.DelCmsAdminRoleHasPermissionsByRolePermissionId(nil, param.RoleId, deleteIds); err != nil {
					kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
					return
				}
			}
			param.Permissions = saveIds
		}
		if len(param.Permissions) > 0 {
			if err := kdaocms.InsertCmsAdminRoleHasPermissionsByRaw(nil, param.RoleId, param.Permissions); err != nil {
				kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
				return
			}
		}
	}

	kbase.SendErrorJsonStr(c, kcode.SUCCESS_STATUS, "")
}

//-----------------------------------------------------------------------------------

func (ts *Cms) logrecordpage(c *gin.Context) {
	page, ok := c.GetQuery("page")
	toPage := 1
	if ok {
		num, err := strconv.Atoi(page)
		if err == nil {
			toPage = num
		}
	}
	pageSize := kcode.PAGE_NUMBER
	pageNum, ok := c.GetQuery("pageSize")
	if ok {
		size, err := strconv.Atoi(pageNum)
		if err == nil {
			pageSize = size
		}
	}
	param := ""
	if searchName, is := c.GetQuery("searchName"); is {
		param = searchName
	}
	prePage := toPage - 1
	if toPage < 1 {
		toPage = 1
	}
	count := kdaocms.CountCmsAdminOptionLog(nil, param)
	totalPage := math.Ceil(float64(count) / float64(pageSize))
	total := int(totalPage)
	if toPage > total {
		toPage = total
	}
	nextPage := toPage + 1
	objs := kdaocms.GetCmsAdminOptionLog(nil, param, int64(toPage), int64(pageSize))
	countNum := len(objs)
	for i := 0; i < countNum; i++ {
		objs[i].CreatedAt = kutils.FormatTime(objs[i].CreatedAt)
	}
	c.HTML(http.StatusOK, "cms/log_list.html", gin.H{
		"lists":      objs,
		"total":      total,
		"page":       toPage,
		"prePage":    prePage,
		"nextPage":   nextPage,
		"searchName": param,
		"pageSize":   pageSize,
		"token":      c.GetString("token"),
	})
}

type logrecorddelBind struct {
	Ids []int64 `form:"ids"  binding:"exists"`
	Url string  `form:"url"  binding:"exists"`
}

func (ts *Cms) logrecorddel(c *gin.Context) {
	var param logrecorddelBind
	callbackName := kbase.GetParam(c, "callback")
	if err := c.ShouldBind(&param); err != nil {
		kinit.LogError.Println(err)
		kbase.SendErrorTokenJsonStr(c, kcode.PARAM_WRONG, callbackName)
		return
	}

	if len(param.Ids) == 0 {
		kbase.SendErrorTokenJsonStr(c, kcode.WRONG_LOGRECORD_NO_CHECK, "")
		return
	}

	if err := kdaocms.DelCmsAdminOptionLogByIds(nil, param.Ids); err != nil {
		kbase.SendErrorTokenJsonStr(c, kcode.OPERATION_WRONG, callbackName)
		return
	}

	kbase.SendErrorOriginJsonStr(c, kcode.SUCCESS_STATUS, param.Url, "")
}

//-----------------------------------------------------------------------------------
